package com.cc.moxingvoice.utils;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;

import com.cc.moxingvoice.R;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Vector;

/**
 * 创建日期：2018/2/28 on 14:33
 * 描述：
 * 作者：郭士超
 * QQ：1169380200
 */

public class FilesUtil {

    // 获取当前目录下所有的文件夹
    public static Vector<String> getFolderName(String fileAbsolutePath) {
        Vector<String> vecFile = new Vector<String>();
        File file = new File(fileAbsolutePath);
        File[] subFile = file.listFiles();

        if (subFile == null) {
            return vecFile;
        }

        for (int iFileLength = 0; iFileLength < subFile.length; iFileLength++) {
            // 判断是否为文件夹
            if (subFile[iFileLength].isDirectory()) {
                String filename = subFile[iFileLength].getName();
                vecFile.add(filename);
            }
        }
        return vecFile;
    }

    // 获取当前目录下所有的mp3文件
    public static Vector<String> getVoiceFileName(String fileAbsolutePath) {
        Vector<String> vecFile = new Vector<String>();
        File file = new File(fileAbsolutePath);
        File[] subFile = file.listFiles();

        for (int iFileLength = 0; iFileLength < subFile.length; iFileLength++) {
            // 判断是否为文件夹
            if (!subFile[iFileLength].isDirectory()) {
                String filename = subFile[iFileLength].getName();
                // 判断是否为MP3结尾
                if (filename.trim().toLowerCase().endsWith(".mp3")
                        || filename.trim().toLowerCase().endsWith(".wma")
                        || filename.trim().toLowerCase().endsWith(".arm")
                        || filename.trim().toLowerCase().endsWith(".m4a")
                        || filename.trim().toLowerCase().endsWith(".wav")
                        // QQ的，需要特殊处理
                        || filename.trim().toLowerCase().endsWith(".slk")
                        || filename.trim().toLowerCase().endsWith(".amr")
                        // 我自己的
                        || filename.trim().toLowerCase().endsWith(".mvod")) {
                    vecFile.add(filename);
                }
            }
        }
        return vecFile;
    }

    // 遍历所有的mp3文件
    public static Vector<String> getAllVoiceFileName(String strPath) {
        Vector<String> voiceList = new Vector<String>();

        String filename;//文件名
        String suf;//文件后缀
        File dir = new File(strPath);//文件夹dir
        File[] files = dir.listFiles();//文件夹下的所有文件或文件夹

        if (files == null) {
            return voiceList;
        }

        for (int i = 0; i < files.length; i++) {
            if (files[i].isDirectory()) {
                voiceList.addAll(getAllVoiceFileName(files[i].getAbsolutePath())); // 递归文件夹！！！
            } else {
                filename = files[i].getName();
                int j = filename.lastIndexOf(".");
                suf = filename.substring(j + 1);//得到文件后缀

                // 判断是否为MP3结尾
                if (suf.equalsIgnoreCase("slk")
                        || suf.equalsIgnoreCase("amr")) {
                    String strFileName = files[i].getAbsolutePath().toLowerCase();
                    voiceList.add(files[i].getAbsolutePath()); // 对于文件才把它的路径加到filelist中
                }
            }
        }
        return voiceList;
    }

    // 获取文件创建时间
    public static long getFileTime(String filePath) {
        File f = new File(filePath);
        if (f.exists()) {
            FileInputStream fis = null;
            try {
                fis = new FileInputStream(f);
                // 文件文件创建时间
//                String time = new SimpleDateFormat("yyyy-MM-dd")
//                        .format(new Date(f.lastModified()));
                return f.lastModified();
            } catch (Exception e) {
                e.printStackTrace();
                return 0;
            }
        }
        return 0;
    }

    // 通过路径获取文件名，带后缀
    public static String getFileNameHandExtension(String pathHandName) {
        if (!isFileExists(pathHandName)) {
            return "未知路径";
        }
        int start = pathHandName.lastIndexOf("/");
//        int end = pathHandName.lastIndexOf(".");
        int end = pathHandName.length();
        if (start != -1 && end != -1) {
            return pathHandName.substring(start + 1, end);
        } else {
            return "未知文件";
        }
    }

    // android获取文件及后缀名    不带.
    public static String[] getFileName(String fileName) {
        int dot = fileName.lastIndexOf(".");
        String str1 = fileName.substring(0, dot);
        String str2 = fileName.substring(dot + 1, fileName.length());
        String[] name = {str1, str2};
        return name;
    }

    /**
     * @param filePath      原始文件路径
     * @param newName       新名称（有后缀）
     * @param admitCopyName 当命名冲突时，是否允许生成副本名（如果是多选重命名的话，是需要允许的；单个文件重命名则设置为不允许）
     * @return 是否修改成功
     * @Description 对文件进行重新命名
     */
    public static boolean fileRename(String filePath, String newName, boolean admitCopyName) {
        //1.判断参数阈值
        if (!isFileExists(filePath) || newName == null || newName.isEmpty()) {
            return false;
        }
        //2.得到原文件全路径
        String oldPath = filePath;
        //3-1.得到文件所在路径
        String rootPath = getPathFromFilepath(oldPath); //得到文件所在路径（即全路径去掉完整文件名）
        //3-2.得到新全路径
        String newPath = makePath(rootPath, newName); //根据根路径和文件名形成新的完整路径
        //4.比较是否变更了名称
        if (oldPath.endsWith(newPath)) { //和原来名称一样，不需要改变
            return true;
        }

        //5.根据新路径得到File类型数据
        File newFile = new File(newPath);
        //6.判断是否已经存在同样名称的文件（即出现重名）
        if (isFileExists(newPath) && !admitCopyName) { //出现重命名且不允许生成副本名
            return false; //重命名失败
        }
        //7.循环判断直到生成可用的副本名
        while (newFile.exists()) {
            //重命名重名定义规范--Util.getCopyNameFromOriginal(String)-自定义方法：根据自定义规则生成原名称副本
            newPath = getCopyNameFromOriginal(newPath);
            newFile = new File(newPath);
        }
        //8.得到原文件File类型数据
        File file = new File(oldPath);
        //9.调用固有方法去重命名
        boolean ret = file.renameTo(newFile);
        /*if (ret) {
            //FIXME:这里通过更改形参来改变实参，是不好的写法，不建议这样写！
            fileInfo.setFileName(getNameFromFilepath(newPath)); //更新文件名
            fileInfo.setmFilePath(newPath); //更新新路径
        }*/
        return ret;
    }

    /**
     * @param originalName 原本的名字，XXX.xx 或者完整路径 xx/xx/XXX.xx ， 也可以没有后缀.xx
     * @return 副本名称
     * @Description 得到文件副本名称，可供粘贴及多选重命名方法使用
     * 命名规则为：普通文件后加“ 1”，若文件末尾已有“ 数字”，则数字递增。
     * 比如，有个文件叫“我.jpg”，使用本方法后得到了“我 1.jpg”，再次使用本方法后得到“我 2.jpg”
     */
    public static String getCopyNameFromOriginal(final String originalName) {
        //1.判断阈值
        if (originalName == null || originalName.isEmpty()) {
            return null;
        }
        String copyName = null;
        //2.得到文件名和后缀名
        String[] nameAndExt = getFileName(getFileNameHandExtension(originalName));
        if (nameAndExt == null) {
            return null;
        }
        String fileName = nameAndExt[0];
        String fileExt = nameAndExt[1];
        //3.判断文件名是否包含我们定义副本规范的标记字符（空格）  原来是空格，我改为_下划线
//        String mark = " ";  // 原来是空格，我改为_下划线
        String mark = "_";  // 原来是空格，我改为_下划线
        if (fileName.contains(mark)) { //如果文件名包涵空格，进行判断是否已经为副本名称
            //4-1.得到end
            String[] array = fileName.split(mark);
            String end = array[array.length - 1]; //得到标记字符后面的值
            //4-2.确保end得到的是最后面的值（防止出现类似路径中的目录也有标记字符的情况，如："mnt/sda/wo de/zhao pian/我的 照片 1.png"）
            while (end.contains(mark)) {
                array = fileName.split(mark);
                end = array[array.length - 1];
            }
            //5.判断标记字符后的字符串是否复合规范（是否是数字）
            boolean isDigit = end.matches("[0-9]+"); //用正则表达式判断是否是正整数
            if (isDigit) {
                try {
                    int index = Integer.parseInt(end) + 1; //递增副本记数
                    int position = fileName.lastIndexOf(mark); //得到最后的空格的位置，用于截取前面的字符串
                    if (position != -1) {
                        //6-1.构造新的副本名（数字递增）
                        copyName = fileName.substring(0, position + 1) + String.valueOf(index);
                    }
                } catch (Exception e) { //转化成整形错误
                    e.printStackTrace();
                    return null;
                }
            } else { //如果空格后不是纯数字，即不为我们定义副本的规范
                //6-2.构造新的副本名（数字初始为1）
                copyName = fileName + mark + "1";
            }
        } else { //如果没有，则变为副本名称格式
            //6-3.构造新的副本名（数字初始为1）
            copyName = fileName + mark + "1";
        }
        //6.返回副本名+后缀名
        String newName = getPathFromFilepath(originalName) + "/" + copyName + "." + fileExt;
        return newName;
    }

    /**
     * @param filepath 文件全路径名称，like mnt/sda/XX.xx
     * @return 根路径，like mnt/sda
     * @Description 得到文件所在路径（即全路径去掉完整文件名）
     */
    public static String getPathFromFilepath(final String filepath) {
        int pos = filepath.lastIndexOf('/');
        if (pos != -1) {
            return filepath.substring(0, pos);
        }
        return "";
    }

    /**
     * @param path1 路径一
     * @param path2 路径二
     * @return 新路径
     * @Description 重新整合路径，将路径一和路径二通过'/'连接起来得到新路径
     */
    public static String makePath(final String path1, final String path2) {
        // 用"/"或File.separator ， 原来用的File.separator，可能一样
        if (path1.endsWith("/")) {
            return path1 + path2;
        }
        return path1 + "/" + path2;
    }

    // 看文件是否存在
    public static boolean isFileExists(String path) {
        try {
            File f = new File(path);
            if (!f.exists()) {
                return false;
            }
        } catch (Exception e) {
            // TODO: handle exception
            return false;
        }
        return true;
    }

    // 创建文件夹
    public static void mkdirPath(String path) {
        //获取内部存储状态
        String state = Environment.getExternalStorageState();
        //如果状态不是mounted，无法读写
        if (!state.equals(Environment.MEDIA_MOUNTED)) {
            return;
        }

        File dir = new File(path);
        if (!dir.exists()) {
            dir.mkdirs();
        }
    }

    // 修改文件及文件夹名
    public static void filesRename(String oldPath, String newPath) {
//        new File("f:/a/a.xlsx").renameTo(new File("f:/a/b.xlsx"));
        //将原文件夹更改为A，其中路径是必要的。注意
        new File(oldPath).renameTo(new File(newPath));
    }

    // 保存图片到本地
    public static void savePic(String path, String fileName, Bitmap bitmap) {
        try {
            File dir = new File(path);
            if (!dir.exists()) {
                dir.mkdirs();
            }
            File file = new File(path, fileName);
            FileOutputStream out = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 保存分享图片到本地+\
     */
    public static void saveSharePic(Context context, String appPath, String fileName) {
        //获取内部存储状态
        String state = Environment.getExternalStorageState();
        //如果状态不是mounted，无法读写
        if (!state.equals(Environment.MEDIA_MOUNTED)) {
            return;
        }

        try {
            File dir = new File(appPath);
            if (!dir.exists()) {
                dir.mkdirs();
            }
            File file = new File(appPath, fileName);
            FileOutputStream out = new FileOutputStream(file);
            // 在这里改分享的图片哦
            Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.liyunlong);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除文件，可以是文件或文件夹
     *
     * @param fileName 要删除的文件名
     * @return 删除成功返回true，否则返回false
     */
    public static boolean delete(String fileName) {
        File file = new File(fileName);
        if (!file.exists()) {
//            System.out.println("删除文件失败:" + fileName + "不存在！");
            return false;
        } else {
            if (file.isFile())
                return deleteFile(fileName);
            else
                return deleteDirectory(fileName);
        }
    }

    /**
     * 删除单个文件
     *
     * @param fileName 要删除的文件的文件名
     * @return 单个文件删除成功返回true，否则返回false
     */
    public static boolean deleteFile(String fileName) {
        File file = new File(fileName);
        // 如果文件路径所对应的文件存在，并且是一个文件，则直接删除
        if (file.exists() && file.isFile()) {
            if (file.delete()) {
//                System.out.println("删除单个文件" + fileName + "成功！");
                return true;
            } else {
//                System.out.println("删除单个文件" + fileName + "失败！");
                return false;
            }
        } else {
//            System.out.println("删除单个文件失败：" + fileName + "不存在！");
            return false;
        }
    }

    /**
     * 删除目录及目录下的文件
     *
     * @param dir 要删除的目录的文件路径
     * @return 目录删除成功返回true，否则返回false
     */
    public static boolean deleteDirectory(String dir) {
        // 如果dir不以文件分隔符结尾，自动添加文件分隔符
        if (!dir.endsWith(File.separator))
            dir = dir + File.separator;
        File dirFile = new File(dir);
        // 如果dir对应的文件不存在，或者不是一个目录，则退出
        if ((!dirFile.exists()) || (!dirFile.isDirectory())) {
//            System.out.println("删除目录失败：" + dir + "不存在！");
            return false;
        }
        boolean flag = true;
        // 删除文件夹中的所有文件包括子目录
        File[] files = dirFile.listFiles();
        for (int i = 0; i < files.length; i++) {
            // 删除子文件
            if (files[i].isFile()) {
                flag = deleteFile(files[i].getAbsolutePath());
                if (!flag)
                    break;
            }
            // 删除子目录
            else if (files[i].isDirectory()) {
                flag = deleteDirectory(files[i]
                        .getAbsolutePath());
                if (!flag)
                    break;
            }
        }
        if (!flag) {
//            System.out.println("删除目录失败！");
            return false;
        }
        // 删除当前目录
        if (dirFile.delete()) {
//            System.out.println("删除目录" + dir + "成功！");
            return true;
        } else {
            return false;
        }

    }

    /**
     * 复制单个文件
     *
     * @param oldPath String 原文件路径 如：c:/fqf.txt
     * @param newPath String 复制后路径 如：f:/fqf.txt
     * @return boolean
     */
    public static void copyFile(String oldPath, String newPath) {
        try {
            int bytesum = 0;
            int byteread = 0;
            File oldfile = new File(oldPath);
            if (oldfile.exists()) { //文件存在时  可能是说文件夹
                InputStream inStream = new FileInputStream(oldPath); //读入原文件
                FileOutputStream fs = new FileOutputStream(newPath);
                byte[] buffer = new byte[1444];
                int length;
                while ((byteread = inStream.read(buffer)) != -1) {
                    bytesum += byteread; //字节数 文件大小
                    System.out.println(bytesum);
                    fs.write(buffer, 0, byteread);
                }
                inStream.close();
            }
        } catch (Exception e) {
//            System.out.println("复制单个文件操作出错");
            e.printStackTrace();

        }

    }

    /**
     * 复制整个文件夹内容
     *
     * @param oldPath String 原文件路径 如：c:/fqf
     * @param newPath String 复制后路径 如：f:/fqf/ff
     * @return boolean
     */
    public static void copyFolder(String oldPath, String newPath) {

        try {
            (new File(newPath)).mkdirs(); //如果文件夹不存在 则建立新文件夹
            File a = new File(oldPath);
            String[] file = a.list();
            File temp = null;
            for (int i = 0; i < file.length; i++) {
                if (oldPath.endsWith(File.separator)) {
                    temp = new File(oldPath + file[i]);
                } else {
                    temp = new File(oldPath + File.separator + file[i]);
                }

                if (temp.isFile()) {
                    FileInputStream input = new FileInputStream(temp);
                    FileOutputStream output = new FileOutputStream(newPath + "/" +
                            (temp.getName()).toString());
                    byte[] b = new byte[1024 * 5];
                    int len;
                    while ((len = input.read(b)) != -1) {
                        output.write(b, 0, len);
                    }
                    output.flush();
                    output.close();
                    input.close();
                }
                if (temp.isDirectory()) {//如果是子文件夹
                    copyFolder(oldPath + "/" + file[i], newPath + "/" + file[i]);
                }
            }
        } catch (Exception e) {
//            System.out.println("复制整个文件夹内容操作出错");
            e.printStackTrace();

        }

    }
}
